<template>
  <div class="clearfix">
    <a-upload :listType="listType" :multiple="multiple" :action="uploadUrl" :headers="headers" :data="{ biz: bizPath }" v-model:fileList="uploadFileList" :beforeUpload="beforeUpload" :disabled="disabled" @change="handleChange" @preview="handlePreview">
      <div v-if="uploadVisible">
        <div v-if="listType == 'picture-card'">
          <LoadingOutlined v-if="loading" />
          <UploadOutlined v-else />
          <div class="ant-upload-text">{{ text }}</div>
        </div>
        <a-button v-if="listType == 'picture'">
          <UploadOutlined></UploadOutlined>
          {{ text }}
        </a-button>
      </div>
    </a-upload>
    <a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel()">
      <img alt="example" style="width: 100%" :src="previewImage" />
    </a-modal>
  </div>
</template>
<script lang="ts">
import { defineComponent, PropType, ref, reactive, watchEffect, computed, unref, watch, onMounted } from 'vue';
import { LoadingOutlined, UploadOutlined } from '@ant-design/icons-vue';
import { useRuleFormItem } from '@/hooks/component/use-form-item';
import { useAttrs } from '@pkg/use';
import { useMessage } from '@/hooks/web/useMessage';
import { getFileAccessHttpUrl, getRandom } from '@pkg/utils';
import { context } from '@pkg/request/bridge';
import { getGlobalConfig } from '@/internal';
const { uploadUrl } = getGlobalConfig();
const { createMessage, createErrorModal } = useMessage();
export default defineComponent({
  name: 'ImageUpload',
  components: { LoadingOutlined, UploadOutlined },
  inheritAttrs: false,
  props: {
    //绑定值
    value: {
      type: [String, Array],
    },
    defaultValue: {
      type: [String, Object],
    },
    //按钮文本
    listType: {
      type: String,
      required: false,
      default: 'picture-card',
    },
    //按钮文本
    text: {
      type: String,
      required: false,
      default: '上传',
    },
    //这个属性用于控制文件上传的业务路径
    bizPath: {
      type: String,
      required: false,
      default: 'temp',
    },
    //是否禁用
    disabled: {
      type: Boolean,
      required: false,
      default: false,
    },
    //上传数量
    fileMax: {
      type: Number,
      required: false,
      default: 1,
    },
  },
  emits: ['options-change', 'change', 'update:value'],
  setup(props, { emit, refs }: any) {
    const emitData = ref<any[]>([]);
    const attrs = useAttrs();
    const token = context.getTokenFunction?.();
    const [state] = useRuleFormItem(props, 'value', 'change', emitData);
    //获取文件名
    const getFileName = (path) => {
      if (path.lastIndexOf('\\') >= 0) {
        let reg = new RegExp('\\\\', 'g');
        path = path.replace(reg, '/');
      }
      return path.substring(path.lastIndexOf('/') + 1);
    };
    //token
    const headers = ref<object>({
      Authorization: token,
    });
    //上传状态
    const loading = ref<boolean>(false);
    //是否是初始化加载
    const isFirstLoad = ref<boolean>(true);
    //文件列表
    let uploadFileList = ref<any[]>([]);
    //预览图
    const previewImage = ref<string | undefined>('');
    //预览框状态
    const previewVisible = ref<boolean>(false);

    //计算是否开启多图上传
    const multiple = computed(() => {
      return props['fileMax'] > 1;
    });

    //计算是否可以继续上传
    const uploadVisible = computed(() => {
      return uploadFileList.value.length < props['fileMax'];
    });
    onMounted(() => {
      isFirstLoad.value = true;
    });
    /**
     * 监听value变化
     */
    watch(
      () => props.value,
      (val, prevCount) => {
        if (val instanceof Array) {
          val = val.join(',');
        }
        if (isFirstLoad.value == true) {
          initFileList(val);
        }
      },
    );

    /**
     * 初始化文件列表
     */
    function initFileList(paths) {
      if (!paths || paths.length == 0) {
        uploadFileList.value = [];
        return;
      }
      let files = <any>[];
      let arr = paths.split(',');
      arr.forEach((value) => {
        let url = getFileAccessHttpUrl(value);
        files.push({
          uid: getRandom(10),
          name: getFileName(value),
          status: 'done',
          url: url,
          response: {
            status: 'history',
            message: value,
          },
        });
      });
      uploadFileList.value = files;
    }

    /**
     * 上传前校验
     */
    function beforeUpload(file) {
      let fileType = file.type;
      if (fileType.indexOf('image') < 0) {
        createMessage.info('请上传图片');
        return false;
      }
    }

    /**
     * 文件上传结果回调
     */
    function handleChange({ file, fileList, event }) {
      console.info('上传文件file', file);
      console.info('event', event);
      console.info('fileList', fileList);
      isFirstLoad.value = false;
      uploadFileList.value = fileList;
      if (file.status === 'error') {
        createMessage.error(`${file.name} 上传失败.`);
      }
      let fileUrls = <any>[];
      //上传完成
      if (file.status != 'uploading') {
        fileList.forEach((file) => {
          if (file.status === 'done') {
            fileUrls.push(file.url || file.response.data.ossPath);
          }
        });
        if (file.status === 'removed') {
          handleDelete(file);
        }
      }
      emitData.value = fileUrls.join(',');
      state.value = fileUrls.join(',');
      emit('update:value', fileUrls.join(','));
    }

    /**
     * 删除图片
     */
    function handleDelete(file) {
      //如有需要新增 删除逻辑
      console.log(file);
    }

    /**
     * 预览图片
     */
    function handlePreview(file) {
      previewImage.value = file.url || file.thumbUrl;
      previewVisible.value = true;
    }

    function getAvatarView() {
      if (uploadFileList.value.length > 0) {
        let url = uploadFileList.value[0].url;
        return getFileAccessHttpUrl(url, null);
      }
    }

    function handleCancel() {
      previewVisible.value = false;
    }

    return {
      state,
      attrs,
      previewImage,
      previewVisible,
      uploadFileList,
      multiple,
      headers,
      loading,
      uploadUrl,
      beforeUpload,
      uploadVisible,
      handlePreview,
      handleCancel,
      handleChange,
    };
  },
});
</script>
<style scoped>
.ant-upload-select-picture-card i {
  font-size: 32px;
  color: #999;
}

.ant-upload-select-picture-card .ant-upload-text {
  margin-top: 8px;
  color: #666;
}
</style>
